(ns client.interface
  "Graphical interface of the project. Contains the methods to create the window and all the graphics necessary for the application"
  (:use client.search
	server.server
	client.client
	(clojure.contrib str-utils))
  (:import (java.security MessageDigest))
  (:require clojure.contrib.gen-html-docs))

(import '(javax.swing JFrame JButton JLabel JPanel JTable JTextField JComboBox DefaultComboBoxModel JCheckBox ImageIcon JScrollPane AbstractButton JMenuBar JMenu JMenuItem)
                                '(javax.swing.table AbstractTableModel)
                                '(java.awt.event ActionListener)
                                '(java.awt BorderLayout FlowLayout Dimension Color))
;The main jtable
(def table (JTable.))

;The database
(def base (str "db-1x2"))

;The combo box used for the days
(def  combo_day (JComboBox.))

(def mode (ref "null"))

(defn describe-mode
  "selects between client or alone mode for describe"
  [base]
  (if (.equals @mode "alone")
    (describe base)
    (if (.equals @mode "net")
      (describe-net base)
      "cant do")))

(defn select-mode
  "selects between client or alone mode for select"
  [base]
  (if (.equals @mode "alone")
    (select base)
    (if (.equals @mode "net")
      (select-net base)
      "cant do")))

(defn out-of-date-mode
  "selects between client or alone mode for out-of-date"
  [base hash]
  (if (.equals @mode "alone")
    (out-of-date base hash)
    (out-of-date-net base hash)))

(defn create-mode
  "selects between client or alone mode for create"
  [base entry]
  (if (.equals @mode "alone")
    (create base entry)
    (if (.equals @mode "net")
      (create-net base entry)
      "cant do")))

(defn delete-mode
  "selects between client or alone mode for select"
  [base recno]
  (if (.equals @mode "alone")
    (delete base recno)
    (if (.equals @mode "net")
      (delete-net base recno)
      "cant do")))

(defn update-mode
  "selects between client or alone mode for select"
  [base num entry]
  (if (.equals @mode "alone")
    (update base num entry)
    (if (.equals @mode "net")
      (update-net base num entry)
      "cant do")))



;The records from the database, a local copy
(def rec (ref (select-mode "db-1x2")))  


;Fields of the table
(def options
     (to-array ["ID" "OWNER" "DATE" "RATE" "SMOKING" "SIZE" "LOCATION" "NAME"])
)

;Color pink
(def red (Color. 255 153 153))
;Color white
(def white (Color. 255 255 255))

(defn setIds
  "Add id to each record"
  [records]
  (loop [result () num 1 rec records]
    (if (= 0 (count rec)) result
                (recur (conj result (assoc (dissoc (first rec) :deleted) :id num)) (inc num) (rest rec))
        )))


(defn convert2D
  "Function that turns the records from the database into a 2D array."
  [records]
  (to-array-2d (map vals records))
)

(defn ourTableModel 
  "Clojure implementation of the AbstractTableModel"
  [rows columnNames]
  (proxy [AbstractTableModel] []
    (getRowCount []    (count rows))
    (getColumnCount [] (count columnNames))
    (getColumnName [column] (nth columnNames column))
    (getValueAt [row column]  (nth (nth rows row) column))
    (isCellEditable [row column] false)))


(defn createAndSetModel
  "Method that updates the Jtable with the new records given to it."
  [records]
  (.setModel table (ourTableModel (convert2D (reverse records)) options))
  )


(defn hashRec
  "Calculate the md5 one way hash of the database"
  []
  (let [md (doto (MessageDigest/getInstance "MD5"))]
    (.update md (.getBytes (serialize @rec)))
    (let [result (.digest md)]
     (str-join "" (map #(Integer/toHexString (bit-and % 0xff)) result)))))


(defn windowOutOfDate
  "Displays a window that inform the user that his database is out of date"
  ([]
  (. javax.swing.JOptionPane (showMessageDialog nil (str "The database is out of date, updating complete")))
  (let []
    (dosync (ref-set rec (select-mode base)))
    (createAndSetModel (setIds  @rec))))
  ([message]
  (. javax.swing.JOptionPane (showMessageDialog nil (str message)))
  (let []
    (dosync (ref-set rec (select-mode base)))
    (createAndSetModel (setIds  @rec)))))



(defn windowSearch
  "Display a window where the user inserts the information that he wants to search"
  []
  (if (.equals (out-of-date-mode base (hashRec)) "up-to-date")
    ""
    (windowOutOfDate))
  (let [
        frameSearch     (JFrame. "Search Window")
        layoutLabels           (FlowLayout. FlowLayout/LEADING 20 8)
        layoutForms            (FlowLayout. FlowLayout/LEADING)
        bOk    	        (JButton. "Ok")
        bCancel         (JButton. "Cancel")     
        text            (JTextField. 10)
        box             (JComboBox. (to-array (first (rest (describe-mode base)))))  
        panelCont       (JPanel.)
        panelLabels     (JPanel.)
        panelForms      (JPanel.)
        panelButtons    (JPanel.)
        labelText       (JLabel. "Enter text to Search:")
        labelBox        (JLabel. "Keyword:        ")
        
        actionCancel (proxy [ActionListener][]
                                        (actionPerformed [event]
                                                                        (.setVisible frameSearch false)))

        
        actionSearch (proxy [ActionListener][]
                                        (actionPerformed [event]
                                                (createAndSetModel (search (setIds @rec) (if (= (str (.getSelectedItem box)) "rate")
                                                                                   (str "$" (.getText text)) 
                                                                                   (str (.getText text))) (keyword (str (.getSelectedItem box))) ))
                                                                                   (.setVisible frameSearch false)))]
    
    (.setDefaultCloseOperation frameSearch JFrame/HIDE_ON_CLOSE)
    (.setPreferredSize frameSearch (Dimension. 330 150))
        
    (.setVerticalTextPosition bOk AbstractButton/CENTER)
    (.setPreferredSize bOk (Dimension. 80 25))
    (.setVerticalTextPosition bCancel AbstractButton/CENTER)
    (.setPreferredSize bCancel (Dimension. 80 25))
    (.setDefaultButton (.getRootPane frameSearch) bOk)
            
    (.setPreferredSize panelCont(Dimension. 330 150))
    (.setPreferredSize panelLabels(Dimension. 150 70))
    (.setPreferredSize panelForms(Dimension. 150 70))
    (.setPreferredSize panelButtons(Dimension. 330 50))
    
    (.add panelLabels labelText)
    (.add panelLabels labelBox)
    (.add panelForms text)    
    (.add panelForms box)
    (.add panelButtons bOk)
    (.add panelButtons bCancel)
    
     
    (.setLayout panelForms layoutForms)
    (.setLayout panelLabels layoutLabels)
    (.add frameSearch BorderLayout/CENTER panelCont)
    (.add panelCont BorderLayout/WEST panelLabels)
    (.add panelCont BorderLayout/EAST panelForms)
    (.add panelCont BorderLayout/SOUTH panelButtons)
    (.addActionListener bCancel actionCancel)
    (.addActionListener bOk actionSearch)
    (.pack frameSearch)
    (.setLocationRelativeTo frameSearch nil)
    (.setVisible frameSearch true)
))
        
(defn checkNumber
	"Checks if the rate is properly formatted"
	[rate bool]
	(loop [i 0 valido bool]
		(if (= i (count rate)) valido
			(recur (inc i) (and valido (Character/isDigit (nth rate i)))  ))	
			
	)
)        

(defn checkString
	"Checks if the string is properly formatted"
	[rate bool]
	(loop [i 0 valido bool]
		(if (= i (count rate)) valido
		(recur (inc i) (and valido (not= (nth rate 0) \ ) (or (Character/isLetter (nth rate i)) (= (nth rate i) \ ) (= (nth rate i) \&))  )))		
	)
) 

(defn isGood
	"Makes the background of the field white"
[field]
(.. field (setBackground white))
1
)


(defn isBad
	"Makes the background of the field red"
[field]
(.. field (setBackground red))
0
)

(defn checkLocName 
	"Checks if Location or Name are properly formatted"
[field]
(if (checkString (.getText field) (> (count (.getText field)) 0)) (isGood field) (isBad field))
)


(defn checkOwner 
	"Checks Owner are properly formatted"
[field]
(if (checkString (.getText field) true) (isGood field) (isBad field))
)


(defn checkRateSize
	"Checks if Rate and size are properly formatted"
[field]
(if (checkNumber (.getText field)  (> (count (.getText field)) 0)) (isGood field) (isBad field))
)


(defn addPadding
	"Adds zeroes to the numbers before 10"
[end]
(for [num (range 1 (inc end))] (if (> num 9) (str num) (str "0" num)))
)

(defn changeDaysOfMonth
"Method that returns the number of days in a given month"
[month]
(cond (= month 2)  (.setModel combo_day (DefaultComboBoxModel. (to-array (addPadding 28))))

(or (= month 4) (= month 6) (= month 9) (= month 11))  
(.setModel combo_day (DefaultComboBoxModel. (to-array (addPadding 30))))

true (.setModel combo_day (DefaultComboBoxModel. (to-array (addPadding 31)))))
)


(defn windowCreate
  "Display a window where the user inserts the data for the new record"
  []
  
  (defn validCreate 
  	[textOwner combo_year combo_month combo_day textRate SmokeCheckBox textSize textLocation textName frameCreate] 
  	(create-mode base 																					
                                                        {:owner (.getText textOwner),          
                                                        :date (apply str (.getSelectedItem combo_year) "/" (.getSelectedItem combo_month) "/" (.getSelectedItem combo_day) ""),  
                                                         :rate (str "$" (.getText textRate) ".00"), 
                                                         :smoking (if (.isSelected SmokeCheckBox) "Y" "N"), 
                                                         :size (.getText textSize), 
                                                         :location (.getText textLocation), 
                                                         :name (.getText textName)})
                                                         
                                                (dosync (ref-set rec (select-mode base)))
                                                (createAndSetModel (setIds @rec))
                                                (.setVisible frameCreate false)  
  )
  
  (if (.equals (out-of-date-mode base (hashRec)) "up-to-date")
    ""
    (windowOutOfDate))
  (let [
        frameCreate     (JFrame. "Create window")
        layoutLabels           (FlowLayout. FlowLayout/LEADING 20 10)
        layoutForms            (FlowLayout. FlowLayout/LEADING)
        bOk                    (JButton. "Ok")
        bCancel                (JButton. "Cancel")     
        bClear                 (JButton. "Clear")
        
        textName               (JTextField. 14)
        textLocation    			 (JTextField. 14)
        textSize               (JTextField. 14)
        SmokeCheckBox 				 (JCheckBox. "Yes")
        textRate               (JTextField. 14)
        combo_year             (JComboBox.) 
        combo_month            (JComboBox.)  
        textOwner              (JTextField. 14)
        panelCont              (JPanel.)
        panelLabels            (JPanel.)
        panelForms             (JPanel.)
        panelButton            (JPanel.)
        labelName       (JLabel. "Name:    ")
        labelLocation 	(JLabel. "Location:")
        labelSize       (JLabel. "Size:       ")
        labelSmoking  	(JLabel. "Smoking:")
        labelRate       (JLabel. "Rate:       ")
        labelDate       (JLabel. "Date:      ")
        labelOwner      (JLabel. "Owner:   ")
        
        actionCancel (proxy [ActionListener][]
                                        (actionPerformed [event]
                                                                        (.setVisible frameCreate false)))
        
        actionComboMonth (proxy [ActionListener][]
                                        (actionPerformed [event]
       	  																		(changeDaysOfMonth (+ 1 (.getSelectedIndex combo_month)))))                                                                        
                                                                      
                                                                        
        actionClear (proxy [ActionListener][]
                                        (actionPerformed [event]
    (.setText textName "")
    (.setBackground textName white)
    (.setText textLocation "")
    (.setBackground textLocation white)
    (.setText textSize "")
    (.setBackground textSize white)
    (.setSelected SmokeCheckBox false)
    (.setText textRate "")
    (.setBackground textRate white)
   (.setSelectedIndex combo_year 0);
    (.setSelectedIndex combo_month 0);
    (.setSelectedIndex combo_day 0);
    (.setText textOwner "")
    (.setBackground textOwner white)))
                                                                        
                                                                        
        actionOk (proxy [ActionListener][]
                                        (actionPerformed [event]
                                        	                     	
                                        	(when (= 1 (* 	(checkOwner textOwner) 
                                        						(checkLocName textLocation) 
                                        						(checkLocName textName)  
                                        						(checkRateSize textRate) 
                                        				(checkRateSize textSize))) 
                                        		(validCreate textOwner combo_year combo_month combo_day textRate SmokeCheckBox textSize textLocation textName frameCreate)
                                            )        
        ))]
     (def year 2010) 
    (.setModel combo_year (DefaultComboBoxModel. (to-array (range year (+ year 11)))))
    (.setModel combo_month (DefaultComboBoxModel. (to-array (addPadding 12)     )))
    (.setModel combo_day (DefaultComboBoxModel. (to-array (addPadding 31))))
    
    (.setDefaultCloseOperation frameCreate JFrame/HIDE_ON_CLOSE)
    (.setPreferredSize frameCreate (Dimension. 320 260))
    
    (.setVerticalTextPosition bOk AbstractButton/CENTER)
    (.setPreferredSize bOk (Dimension. 80 25))
    (.setVerticalTextPosition bCancel AbstractButton/CENTER)
    (.setPreferredSize bCancel (Dimension. 80 25))
    (.setVerticalTextPosition bClear AbstractButton/CENTER)
    (.setPreferredSize bClear (Dimension. 80 25))
    (.setDefaultButton (.getRootPane frameCreate) bOk)

    (.setLayout panelForms layoutForms)
    (.setLayout panelLabels layoutLabels)
    (.setPreferredSize panelCont(Dimension. 320 250))
    (.setPreferredSize panelLabels(Dimension. 80 185))
    (.setPreferredSize panelForms(Dimension. 210 185))
    (.setPreferredSize panelButton(Dimension. 263 30))
      	
    (.add panelLabels labelName)
    (.add panelForms textName)
    (.add panelLabels labelLocation)   
    (.add panelForms textLocation)
    (.add panelLabels labelSize)   
    (.add panelForms textSize)  
    (.add panelLabels labelSmoking)  
    (.add panelForms SmokeCheckBox) 
    (.add panelLabels labelRate)  
    (.add panelForms textRate)  
    (.add panelLabels labelDate)  
    (.add panelForms combo_year)
    (.add panelForms combo_month)
    (.add panelForms combo_day)
    (.add panelLabels labelOwner)  
    (.add panelForms textOwner)
      
      (.add panelButton bOk)
      (.add panelButton bCancel)
      (.add panelButton bClear)
      
      (.add frameCreate BorderLayout/NORTH panelCont)
      (.add panelCont BorderLayout/CENTER panelLabels)
      (.add panelCont BorderLayout/EAST panelForms)
      (.add panelCont BorderLayout/SOUTH panelButton)
      (.addActionListener bCancel actionCancel)
      (.addActionListener bOk actionOk)
      (.addActionListener bClear actionClear)
      (.addActionListener combo_month actionComboMonth)
    (.pack frameCreate)
    (.setLocationRelativeTo frameCreate nil)
    (.setVisible frameCreate true)))

 
(defn substring
	"Returns the substring used for the rate"
	[rate]
(apply str (take (- (count rate) 4) (drop 1 rate)))
)
        
(defn windowUpdate
  "Display a window that lets the user insert the data for the record that will be updated"
  [numberRow]
  (defn validUpdate
	[numberRow textOwner textDate textRate SmokeCheckBox textSize textLocation textName frameUpdate]
	
	
	(if (.equals (out-of-date-mode base (hashRec)) "up-to-date")
					(let []
					  (update-mode base (.. table (getValueAt numberRow 0)) 
						  {:owner (.getText textOwner), 
						   :date (.getText textDate), 
						   :rate (str "$" (.getText textRate) ".00"), 
						   :smoking (if (.isSelected SmokeCheckBox) "Y" "N"), 
						   :size (.getText textSize), 
						   :location (.getText textLocation), 
						   :name (.getText textName)})
					  (dosync (ref-set rec (select-mode base)))
					  (createAndSetModel (setIds @rec)))
					  
					(windowOutOfDate))
	
	(.setVisible frameUpdate false)
)
  
  (if (.equals (out-of-date-mode base (hashRec)) "up-to-date")
    ""
    (windowOutOfDate))
    (let [
    frameUpdate             (JFrame. "Update window")
    layoutLabels           (FlowLayout. FlowLayout/LEADING 20 10)
    layoutForms            (FlowLayout. FlowLayout/LEADING)
	  bOk                             (JButton. "Ok")
	  bCancel                         (JButton. "Cancel")
	 
	  textName               (JTextField. 14)
    textLocation    			 (JTextField. 14)
    textSize               (JTextField. 14)
    SmokeCheckBox 				 (JCheckBox. "Yes")
    textRate               (JTextField. 14)
	  textDate               (JTextField. 14)
	  textOwner              (JTextField. 14)
        panelCont              (JPanel.)
        panelLabels            (JPanel.)
        panelForms             (JPanel.)
        panelButton            (JPanel.)
        labelName       (JLabel. "Name:    ")
        labelLocation 	(JLabel. "Location:")
        labelSize       (JLabel. "Size:       ")
        labelSmoking  	(JLabel. "Smoking:")
        labelRate       (JLabel. "Rate:       ")
        labelDate       (JLabel. "Date:      ")
        labelOwner      (JLabel. "Owner:   ")
	  
	  actionCancel (proxy [ActionListener][]
			 (actionPerformed [event]
					  (.setVisible frameUpdate false)))
	  
	  actionOk (proxy [ActionListener][]
		     (actionPerformed [event]
		     	 
		     	 (when (= 1 (* 	(checkOwner textOwner) 
                                        						(checkLocName textLocation) 
                                        						(checkLocName textName)  
                                        						(checkRateSize textRate) 
                                        						(checkRateSize textSize))) 
                                        		(validUpdate numberRow textOwner textDate textRate SmokeCheckBox textSize textLocation textName frameUpdate)
                                            )
                                            
				      ))
	  ]
      
      (.setDefaultCloseOperation frameUpdate JFrame/HIDE_ON_CLOSE)
      (.setPreferredSize frameUpdate (Dimension. 320 260))
      
      (.setVerticalTextPosition bOk AbstractButton/CENTER)
      (.setPreferredSize bOk (Dimension. 80 25))
      (.setVerticalTextPosition bCancel AbstractButton/CENTER)
      (.setPreferredSize bCancel (Dimension. 80 25))
      (.setDefaultButton (.getRootPane frameUpdate) bOk)
            
      (.setText textName (.. table (getValueAt numberRow 7)))
      (.setText textLocation (.. table (getValueAt numberRow 6)))
      (.setText textSize (.. table (getValueAt numberRow 5)))
      (.setSelected SmokeCheckBox (.equals (.. table (getValueAt numberRow 4)) "Y"))
      (.setText textRate (substring (.. table (getValueAt numberRow 3))))
      (.setText textDate (.. table (getValueAt numberRow 2)))
      (.setText textOwner (.. table (getValueAt numberRow 1)))
      
      
      (.setLayout panelForms layoutForms)
      (.setLayout panelLabels layoutLabels)
      (.setPreferredSize panelCont(Dimension. 320 250))
      (.setPreferredSize panelLabels(Dimension. 80 185))
      (.setPreferredSize panelForms(Dimension. 210 185))
      (.setPreferredSize panelButton(Dimension. 263 30))
      	
      (.add panelLabels labelName)
    (.add panelForms textName)
    (.add panelLabels labelLocation)   
    (.add panelForms textLocation)
    (.add panelLabels labelSize)   
    (.add panelForms textSize)  
    (.add panelLabels labelSmoking)  
    (.add panelForms SmokeCheckBox) 
    (.add panelLabels labelRate)  
    (.add panelForms textRate)  
    (.add panelLabels labelDate)  
      (.add panelForms textDate) 
       (.add panelLabels labelOwner)  
    (.add panelForms textOwner)
      
      (.add panelButton bOk)
      (.add panelButton bCancel)
     
      
      (.add frameUpdate BorderLayout/NORTH panelCont)
      (.add panelCont BorderLayout/CENTER panelLabels)
      (.add panelCont BorderLayout/EAST panelForms)
      (.add panelCont BorderLayout/SOUTH panelButton)
      (.addActionListener bCancel actionCancel)
      (.addActionListener bOk actionOk)
      (.pack frameUpdate)
      (.setLocationRelativeTo frameUpdate nil)
      (.setVisible frameUpdate true)))

    
(def selection
     (to-array ["Ok" "Cancel"])
)

(defn windowDelete
        "Display a window to confirm the elimination of a record"
        [number]
	 (if (.equals (out-of-date-mode base (hashRec)) "up-to-date")
	   (if (= 0 (. javax.swing.JOptionPane (showOptionDialog nil 
                                                                 (str "Are you sure you want to remove the record?")
								 "Question"
								 javax.swing.JOptionPane/YES_NO_CANCEL_OPTION
								 javax.swing.JOptionPane/QUESTION_MESSAGE
								 nil,
								 selection
								 (get selection 1))))
	     
	       (if (.equals (out-of-date-mode base (hashRec)) "up-to-date")
		(let [] 
		  (delete-mode base (.. table (getValueAt number 0))) 
		  (dosync (ref-set rec (select-mode base)))
		  (createAndSetModel (setIds  @rec)))
		(windowOutOfDate "Database out of date, will be updated, please try again")))
	   (windowOutOfDate "Database out of date, will be updated, please try again")))

	   	   
(defn windowAbout
	""
	[]
	(let [
		frameAbout 			(JFrame. "About System")
		panelContainer  (JPanel.)
		buttonOk				(JButton. "Ok")
		textLabelI				(JLabel. "                          ")
    textLabel				(JLabel. "This system is brought by:")
    textLabelE				(JLabel. "                          ")
    textLabelA				(JLabel. "Ana I. Rodríguez")
    textLabelJ				(JLabel. "Jorge Rodríguez")
    textLabelG				(JLabel. "Gianfranco Arroyo")
    textLabelO				(JLabel. "                          ")

    actionOk (proxy [ActionListener][]
                     (actionPerformed [event]
                           (.setVisible frameAbout false)))
        		
				]
								
	
		(.setDefaultCloseOperation frameAbout JFrame/HIDE_ON_CLOSE)
    (.setPreferredSize frameAbout (Dimension. 200 210))				
		
    (.setVerticalTextPosition buttonOk AbstractButton/CENTER)
    (.setPreferredSize buttonOk (Dimension. 80 25))
   	(.setDefaultButton (.getRootPane frameAbout) buttonOk)		
		
		(.setPreferredSize panelContainer(Dimension. 200 210))
		(.add panelContainer BorderLayout/NORTH textLabelI)
		(.add panelContainer BorderLayout/NORTH textLabel)
		(.add panelContainer BorderLayout/NORTH textLabelE)
		(.add panelContainer BorderLayout/NORTH textLabelA)
		(.add panelContainer BorderLayout/NORTH textLabelJ)
		(.add panelContainer BorderLayout/NORTH textLabelG)
		(.add panelContainer BorderLayout/NORTH textLabelO)
		(.add panelContainer BorderLayout/SOUTH buttonOk)
				
		(.add frameAbout BorderLayout/CENTER panelContainer)
		(.addActionListener buttonOk actionOk)
		(.pack frameAbout)
		(.setLocationRelativeTo frameAbout nil)
		(.setVisible frameAbout true)))
	   
	   
	   
	   
    
(defn windowMain
  "Display the main window"
  [title]
  (let [
  frame 			(JFrame. title)
  menuBar 	 	(JMenuBar. )
  file    	 	(JMenu. "File")
  edit    	 	(JMenu. "Edit")
  menuSearch 	(JMenu. "Search")
  help    	 	(JMenu. "Help")
  exitItem		(JMenuItem. "Exit")
  showItem		(JMenuItem. "Show All")
  createItem	(JMenuItem. "Create")
  updateItem	(JMenuItem. "Update")
  deleteItem	(JMenuItem. "Delete")
  searchItem	(JMenuItem. "Search...")
  aboutItem		(JMenuItem. "About")
	bSearch     (JButton. "Search")
	bCreate 		(JButton. "Create")
	bUpdate			(JButton. "Update")
	bDelete			(JButton. "Delete")
	bShow				(JButton. "Show All")
	labelHotel 	(JLabel.)
	scrollPane  (JScrollPane. table)
	panelInit   (JPanel.)
	panelButton (JPanel.)
	panelTable 	(JPanel.)
	
	windowSizeX     	800
  windowSizeY     	600
  
  panelInitSizeX		windowSizeX 
  panelInitSizeY		120
  
  panelButtonSizeX	150 
  panelButtonSizeY	480
  
  menuSizeX					windowSizeX
  menuSizeY					20
  
  buttonSizeX				90
  buttonSizeY				25
  
  actionExit (proxy [ActionListener] []
          	(actionPerformed [event]
          		(System/exit 0)
  						))
  						  
	actionButtonShow (proxy [ActionListener][]
						(actionPerformed [event]
								 (dosync (ref-set rec (select-mode base)))
								 (createAndSetModel (setIds @rec))
								 ))
	
	actionButtonSearch (proxy [ActionListener][]
			     (actionPerformed [event]
					      (windowSearch)	
					      ))
	
	actionButtonCreate (proxy [ActionListener][]
			     (actionPerformed [event]
					      (windowCreate)
					      ))

	actionButtonUpdate (proxy [ActionListener][]
			     (actionPerformed [event]
			     	 (if (= -1 (.getSelectedRow table))
			     	 	  (. javax.swing.JOptionPane (showMessageDialog nil "Please, you must select a row!" "ALERT" javax.swing.JOptionPane/WARNING_MESSAGE))
			     	 (windowUpdate (.getSelectedRow table)))
					      ))

	
	actionButtonDelete (proxy [ActionListener][]
			     (actionPerformed [event]
			     	 (if (= -1 (.getSelectedRow table))
			     	 	  (. javax.swing.JOptionPane (showMessageDialog nil "Please, you must select a row!" "ALERT" javax.swing.JOptionPane/WARNING_MESSAGE))
			     	 (windowDelete (.getSelectedRow table)))
					      ))
					      
	actionAbout (proxy [ActionListener] []
          	(actionPerformed [event]
          		(windowAbout)
  						))
	]
    
    "Properties of frame"
    (.setDefaultCloseOperation frame JFrame/EXIT_ON_CLOSE)
    (.setPreferredSize frame (Dimension. windowSizeX windowSizeY))
         
    "Properties of menuBar"
    (.setPreferredSize menuBar (Dimension. menuSizeX menuSizeY))
    (.add menuBar file)
    (.add menuBar edit)
    (.add menuBar menuSearch)
    (.add menuBar help)
    (.add file showItem)
    (.add file exitItem)
    (.add edit createItem)
    (.add edit updateItem)
    (.add edit deleteItem)
    (.add menuSearch searchItem)
    (.add help aboutItem)
    
             
    "Properties of panelInit"
    (.setPreferredSize panelInit(Dimension. panelInitSizeX panelInitSizeY))
    (.setBackground panelInit (Color. 123,12,5))
    (.setLayout panelInit (BorderLayout.))
    (.setIcon labelHotel (ImageIcon. (ClassLoader/getSystemResource"client/hotel.jpg")))
    (.setHorizontalAlignment labelHotel JLabel/CENTER)
    (.setVerticalAlignment labelHotel JLabel/CENTER)
    (.add panelInit BorderLayout/NORTH menuBar)
    (.add panelInit BorderLayout/SOUTH labelHotel)
    
    "Properties of table"
    (.setAutoResizeMode table JTable/AUTO_RESIZE_SUBSEQUENT_COLUMNS)
    (.setFillsViewportHeight table true)
    (.setModel table (ourTableModel
		      (to-array-2d [[nil nil nil nil nil nil nil nil nil]])
		      options))
		      		     
    "Properties of panelTable"
    (.setLayout panelTable (BorderLayout.))
    (.add panelTable scrollPane BorderLayout/CENTER)

		"Properties of buttons"
		(.setVerticalTextPosition bSearch AbstractButton/CENTER)
		(.setPreferredSize bSearch (Dimension. buttonSizeX buttonSizeY))
		(.setVerticalTextPosition bCreate AbstractButton/CENTER)
		(.setPreferredSize bCreate(Dimension. buttonSizeX buttonSizeY))
		(.setVerticalTextPosition bUpdate AbstractButton/CENTER)
		(.setPreferredSize bUpdate (Dimension. buttonSizeX buttonSizeY))
		(.setVerticalTextPosition bDelete AbstractButton/CENTER)
		(.setPreferredSize bDelete (Dimension. buttonSizeX buttonSizeY))
		(.setVerticalTextPosition bShow AbstractButton/CENTER)
		(.setPreferredSize bShow (Dimension. buttonSizeX buttonSizeY))
        
    "Properties of panelButton"
    (.setPreferredSize panelButton (Dimension. panelButtonSizeX panelButtonSizeY))
    (.setBackground panelButton (Color. 123,12,5))
    (.add panelButton bSearch)
    (.add panelButton bCreate)
    (.add panelButton bUpdate)
    (.add panelButton bDelete)
    (.add panelButton bShow)
   
    "Add components to the frame"
    (.add frame BorderLayout/NORTH panelInit)
    (.add frame BorderLayout/CENTER panelTable)
    (.add frame BorderLayout/EAST panelButton)
    (.addActionListener showItem actionButtonShow)
    (.addActionListener exitItem actionExit)
    (.addActionListener createItem actionButtonCreate)
    (.addActionListener updateItem actionButtonUpdate)
    (.addActionListener deleteItem actionButtonDelete)
    (.addActionListener searchItem actionButtonSearch)
    (.addActionListener aboutItem actionAbout)
    
    (.addActionListener bShow actionButtonShow)
    (.addActionListener bSearch actionButtonSearch)
    (.addActionListener bCreate actionButtonCreate)
    (.addActionListener bUpdate actionButtonUpdate)
    (.addActionListener bDelete actionButtonDelete)
    (.pack frame)
    (.setLocationRelativeTo frame nil)
    (.setVisible frame true)))

(defn client-start
  "Method that calls the interface and makes it start"
  ([mode-selection]
     (dosync (ref-set mode mode-selection))
     (dosync (ref-set rec (select-mode base)))
     (windowMain "HOME PAGE URLYBIRD")
     (createAndSetModel (setIds @rec)))
  ([mode-selection server port]
      (dosync (ref-set mode mode-selection))
      (where-to port server)
      (dosync (ref-set rec (select-mode base)))
      (windowMain "HOME PAGE URLYBIRD")
      (createAndSetModel (setIds @rec))))
     


